package edu.lnu.project.timeeditapp.db;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import edu.lnu.project.timeeditapp.helper.MyHelper;
import edu.lnu.project.timeeditapp.parser.Event;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

public class TimeEditDataSource {

	// Database fields
	private SQLiteDatabase database;
	private TimeEditDbHelper dbHelper;
	private String[] allColumns = { TimeEditDbHelper.COLUMN_ID,
			TimeEditDbHelper.COLUMN_WEEKDAY, TimeEditDbHelper.COLUMN_BEGINDATE,
			TimeEditDbHelper.COLUMN_BEGINTIME, TimeEditDbHelper.COLUMN_ENDDATE,
			TimeEditDbHelper.COLUMN_ENDTIME, TimeEditDbHelper.COLUMN_COURSE, TimeEditDbHelper.COLUMN_PROGRAMME,
			TimeEditDbHelper.COLUMN_COURSEEVENT, TimeEditDbHelper.COLUMN_PROGRAMMEEVENT,
			TimeEditDbHelper.COLUMN_ROOM, TimeEditDbHelper.COLUMN_TEACHER,
			TimeEditDbHelper.COLUMN_STUDENTGROUP, TimeEditDbHelper.COLUMN_ACTIVITY,
			TimeEditDbHelper.COLUMN_EXAMCODE, TimeEditDbHelper.COLUMN_COMMENTS,
			TimeEditDbHelper.COLUMN_CITY, TimeEditDbHelper.COLUMN_REMINDER,
			TimeEditDbHelper.COLUMN_WEEK};

	public TimeEditDataSource(Context context) {
		dbHelper = new TimeEditDbHelper(context);
	}

	public void open() throws SQLException {
		database = dbHelper.getWritableDatabase();
	}

	public void close() {
		dbHelper.close();
	}

	//Create the event by entering every attribute of the event.
	public Event createEvent(String	weekday, String beginDate, String beginTime,
			String endDate, String	endTime, String	course, String	programme,
			String	courseEvt, String	programmeEvt, String	room,
			String	teacher, String	studentGroup, String	activity,
			String	examCode, String comments, String	city, int reminder, int week) {

		ContentValues values = new ContentValues();
		values.put(TimeEditDbHelper.COLUMN_WEEKDAY, weekday);
		values.put(TimeEditDbHelper.COLUMN_BEGINDATE, beginDate);
		values.put(TimeEditDbHelper.COLUMN_BEGINTIME, beginTime);
		values.put(TimeEditDbHelper.COLUMN_ENDDATE, endDate);
		values.put(TimeEditDbHelper.COLUMN_ENDTIME, endTime);
		values.put(TimeEditDbHelper.COLUMN_COURSE, course);
		values.put(TimeEditDbHelper.COLUMN_PROGRAMME, programme);
		values.put(TimeEditDbHelper.COLUMN_COURSEEVENT, courseEvt);
		values.put(TimeEditDbHelper.COLUMN_PROGRAMMEEVENT, programmeEvt);
		values.put(TimeEditDbHelper.COLUMN_ROOM, room);
		values.put(TimeEditDbHelper.COLUMN_TEACHER, teacher);
		values.put(TimeEditDbHelper.COLUMN_STUDENTGROUP, studentGroup);
		values.put(TimeEditDbHelper.COLUMN_ACTIVITY, activity);
		values.put(TimeEditDbHelper.COLUMN_EXAMCODE, examCode);
		values.put(TimeEditDbHelper.COLUMN_COMMENTS, comments);
		values.put(TimeEditDbHelper.COLUMN_CITY, city);
		values.put(TimeEditDbHelper.COLUMN_REMINDER, reminder);
		values.put(TimeEditDbHelper.COLUMN_WEEK, week);

		long insertId = database.insert(TimeEditDbHelper.TIMETABLE_TABLE_NAME, null, values);
		Cursor cursor = database.query(TimeEditDbHelper.TIMETABLE_TABLE_NAME,
				allColumns, TimeEditDbHelper.COLUMN_ID + " = " + insertId, null,
				null, null, null);
		cursor.moveToFirst();
		Event newEvent = cursorToEvent(cursor);
		cursor.close();

		return newEvent;
	}

	//Create the event by entering the event object.
	public Event createEvent (Event event){

		ContentValues values = new ContentValues();
		values.put(TimeEditDbHelper.COLUMN_WEEKDAY, event.getWeekday());
		values.put(TimeEditDbHelper.COLUMN_BEGINDATE, event.getBeginDate());
		values.put(TimeEditDbHelper.COLUMN_BEGINTIME, event.getBeginTime());
		values.put(TimeEditDbHelper.COLUMN_ENDDATE, event.getEndDate());
		values.put(TimeEditDbHelper.COLUMN_ENDTIME, event.getEndTime());
		values.put(TimeEditDbHelper.COLUMN_COURSE, event.getCourse());
		values.put(TimeEditDbHelper.COLUMN_PROGRAMME, event.getProgramme());
		values.put(TimeEditDbHelper.COLUMN_COURSEEVENT, event.getCourseEvt());
		values.put(TimeEditDbHelper.COLUMN_PROGRAMMEEVENT, event.getProgrammeEvt());
		values.put(TimeEditDbHelper.COLUMN_ROOM, event.getRoom());
		values.put(TimeEditDbHelper.COLUMN_TEACHER, event.getTeacher());
		values.put(TimeEditDbHelper.COLUMN_STUDENTGROUP, event.getStudentGroup());
		values.put(TimeEditDbHelper.COLUMN_ACTIVITY, event.getActivity());
		values.put(TimeEditDbHelper.COLUMN_EXAMCODE, event.getExamCode());
		values.put(TimeEditDbHelper.COLUMN_COMMENTS, event.getComments());
		values.put(TimeEditDbHelper.COLUMN_CITY, event.getCity());
		values.put(TimeEditDbHelper.COLUMN_REMINDER, 0);
		values.put(TimeEditDbHelper.COLUMN_WEEK, getWeek(event.getBeginDate()));//get the week method

		long insertId = database.insert(TimeEditDbHelper.TIMETABLE_TABLE_NAME, null, values);
		Cursor cursor = database.query(TimeEditDbHelper.TIMETABLE_TABLE_NAME,
				allColumns, TimeEditDbHelper.COLUMN_ID + " = " + insertId, null,
				null, null, null);
		cursor.moveToFirst();
		Event newEvent = cursorToEvent(cursor);
		cursor.close();

		return newEvent;
	}

	/**
	 * Removes all events from database
	 */
	public void deleteAllEvents(){
		//Get all events
		ArrayList<Event> events = getAllEvents();

		//Remove all events in events array list.
		for(Event event : events){
			deleteEvent(event);
		}
	}


	/*TODO: This method below might be redundant because
	 *either way we use the id only to perform deletion.
	 */
	
	/**
	 * Removes an event by entering the event object.
	 */
	public void deleteEvent(Event Event) {
		long id = Event.getId();
		database.delete(TimeEditDbHelper.TIMETABLE_TABLE_NAME, TimeEditDbHelper.COLUMN_ID
				+ " = " + id, null);
	}

	/**
	 * Removes an event by entering its id.
	 */
	public void deleteEvent(int id) {
		database.delete(TimeEditDbHelper.TIMETABLE_TABLE_NAME, TimeEditDbHelper.COLUMN_ID
				+ " = " + id, null);
	}

	/**
	 * Get the event by entering its id.
	 */
	public Event getEvent(long id) {
		String restrict = TimeEditDbHelper.COLUMN_ID + "=" + id;
		Cursor cursor = database.query(true, TimeEditDbHelper.TIMETABLE_TABLE_NAME, allColumns, restrict, 
				null, null, null, null, null);
		if (cursor != null && cursor.getCount() > 0) {
			cursor.moveToFirst();
			Event Event = cursorToEvent(cursor);

			// Make sure to close the cursor
			cursor.close();
			return Event;
		}
		// Make sure to close the cursor
		cursor.close();
		return null;
	}

	//There should be a method where we can fetch the data that we won't update so the code looks more clean
	public boolean updateEvent(int eventId, String	weekday, String beginDate, String beginTime,
			String endDate, String	endTime, String	course, String	programme,
			String	courseEvt, String	programmeEvt, String	room,
			String	teacher, String	studentGroup, String	activity,
			String	examCode, String	comments, String	city, boolean reminder, int week ) {
		ContentValues values = new ContentValues();
		values.put(TimeEditDbHelper.COLUMN_WEEKDAY, weekday);
		values.put(TimeEditDbHelper.COLUMN_BEGINDATE, beginDate);
		values.put(TimeEditDbHelper.COLUMN_BEGINTIME, beginTime);
		values.put(TimeEditDbHelper.COLUMN_ENDDATE, endDate);
		values.put(TimeEditDbHelper.COLUMN_ENDTIME, endTime);
		values.put(TimeEditDbHelper.COLUMN_COURSE, course);
		values.put(TimeEditDbHelper.COLUMN_PROGRAMME, programme);
		values.put(TimeEditDbHelper.COLUMN_COURSEEVENT, courseEvt);
		values.put(TimeEditDbHelper.COLUMN_PROGRAMMEEVENT, programmeEvt);
		values.put(TimeEditDbHelper.COLUMN_ROOM, room);
		values.put(TimeEditDbHelper.COLUMN_TEACHER, teacher);
		values.put(TimeEditDbHelper.COLUMN_STUDENTGROUP, studentGroup);
		values.put(TimeEditDbHelper.COLUMN_ACTIVITY, activity);
		values.put(TimeEditDbHelper.COLUMN_EXAMCODE, examCode);
		values.put(TimeEditDbHelper.COLUMN_COMMENTS, comments);
		values.put(TimeEditDbHelper.COLUMN_CITY, city);
		values.put(TimeEditDbHelper.COLUMN_REMINDER, reminder);
		values.put(TimeEditDbHelper.COLUMN_WEEK, week);

		String restrict = TimeEditDbHelper.COLUMN_ID + "=" + eventId;
		return database.update(TimeEditDbHelper.TIMETABLE_TABLE_NAME, values, restrict , null) > 0;
	}

	public boolean updateEventReminder(Event event, int reminder ) {
		ContentValues values = new ContentValues();
		values.put(TimeEditDbHelper.COLUMN_WEEKDAY, event.getWeekday());
		values.put(TimeEditDbHelper.COLUMN_BEGINDATE, event.getBeginDate());
		values.put(TimeEditDbHelper.COLUMN_BEGINTIME, event.getBeginTime());
		values.put(TimeEditDbHelper.COLUMN_ENDDATE, event.getEndDate());
		values.put(TimeEditDbHelper.COLUMN_ENDTIME, event.getEndTime());
		values.put(TimeEditDbHelper.COLUMN_COURSE, event.getCourse());
		values.put(TimeEditDbHelper.COLUMN_PROGRAMME, event.getProgramme());
		values.put(TimeEditDbHelper.COLUMN_COURSEEVENT, event.getCourseEvt());
		values.put(TimeEditDbHelper.COLUMN_PROGRAMMEEVENT, event.getProgrammeEvt());
		values.put(TimeEditDbHelper.COLUMN_ROOM, event.getRoom());
		values.put(TimeEditDbHelper.COLUMN_TEACHER, event.getTeacher());
		values.put(TimeEditDbHelper.COLUMN_STUDENTGROUP, event.getStudentGroup());
		values.put(TimeEditDbHelper.COLUMN_ACTIVITY, event.getActivity());
		values.put(TimeEditDbHelper.COLUMN_EXAMCODE, event.getExamCode());
		values.put(TimeEditDbHelper.COLUMN_COMMENTS, event.getComments());
		values.put(TimeEditDbHelper.COLUMN_CITY, event.getCity());
		values.put(TimeEditDbHelper.COLUMN_REMINDER, reminder);
		values.put(TimeEditDbHelper.COLUMN_WEEK, event.getWeek());

		String restrict = TimeEditDbHelper.COLUMN_ID + "=" + event.getId();
		return database.update(TimeEditDbHelper.TIMETABLE_TABLE_NAME, values, restrict , null) > 0;
	}

	private Event cursorToEvent(Cursor cursor) { 
		Event event = new Event();
		event.setId(cursor.getInt(0));
		event.setWeekday(cursor.getString(1));
		event.setBeginDate(cursor.getString(2));
		event.setBeginTime(cursor.getString(3));
		event.setEndDate(cursor.getString(4));
		event.setEndTime(cursor.getString(5));
		event.setCourse(cursor.getString(6));
		event.setProgramme(cursor.getString(7));
		event.setCourseEvt(cursor.getString(8));
		event.setProgrammeEvt(cursor.getString(9));
		event.setRoom(cursor.getString(10));
		event.setTeacher(cursor.getString(11));
		event.setStudentGroup(cursor.getString(12));
		event.setActivity(cursor.getString(13));
		event.setExamCode(cursor.getString(14));
		event.setComments(cursor.getString(15));
		event.setCity(cursor.getString(16));
		event.setReminder(cursor.getInt(17));
		event.setWeek(cursor.getInt(18));

		return event;
	}

	private String cursorToEventName(Cursor cursor) { 
		String eventName = cursor.getString(0);
		return eventName;
	}

	public ArrayList<Event> getAllEvents() {
		ArrayList<Event> EventEntities = new ArrayList<Event>();

		Cursor cursor = database.query(TimeEditDbHelper.TIMETABLE_TABLE_NAME,
				allColumns, null, null, null, null, null);

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Event Event = cursorToEvent(cursor);
			EventEntities.add(Event);
			cursor.moveToNext();
		}
		// Make sure to close the cursor
		cursor.close();
		return EventEntities;
	}

	public int getWeek(String input){
		String format = "yyyy-MM-dd";

		int week = 0;
		SimpleDateFormat df = new SimpleDateFormat(format);
		Date date;
		try {
			date = df.parse(input);
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			week = cal.get(Calendar.WEEK_OF_YEAR);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return week;
	}

	/**
	 * Returns the last week that we have events for
	 * @return int (the week in the last event )
	 */
	public int getLastWeek(){

		//Get all events
		ArrayList<Event> events = getAllEvents();

		//Return the week in the last event
		return getWeek( events.get( events.size()-1 ).getBeginDate());
	}

	/**
	 * Returns the first week that we have events for
	 * @return int (the week in the first event )
	 */
	public int getFirstWeek(){

		//Return the week in the first event
		return getWeek(getAllEvents().get(0).getBeginDate());
	}

	public ArrayList<Event> getWeekEvents(int week){
		String restrict = TimeEditDbHelper.COLUMN_WEEK + "=" + week;
		String query = TimeEditDbHelper.COLUMN_BEGINDATE + " " + "ASC";

		Cursor cursor = database.query(true, TimeEditDbHelper.TIMETABLE_TABLE_NAME, allColumns, restrict, 
				null, null, null, query, null);
		ArrayList<Event> listOfEvents = new ArrayList<Event>();

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Event eventEntity = cursorToEvent(cursor);
			listOfEvents.add(eventEntity);
			cursor.moveToNext();
		}
		// Make sure to close the cursor
		cursor.close();
		return listOfEvents;

	}

	public ArrayList<Event> getTodaysEvents(){

		String restrict = TimeEditDbHelper.COLUMN_BEGINDATE + "=" + MyHelper.getTodaysDate();
		Cursor cursor = database.query(true, TimeEditDbHelper.TIMETABLE_TABLE_NAME, allColumns, restrict, 
				null, null, null, null, null);
		ArrayList<Event> listOfEvents = new ArrayList<Event>();

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Event eventEntity = cursorToEvent(cursor);
			listOfEvents.add(eventEntity);
			cursor.moveToNext();
		}
		// Make sure to close the cursor
		cursor.close();
		return listOfEvents;

	}

	public ArrayList<String> getAllEventNames(){

		Cursor cursor = database.query(true, TimeEditDbHelper.TIMETABLE_TABLE_NAME, new String[]{TimeEditDbHelper.COLUMN_COURSE}, null, 
				null, null, null, null, null);
		ArrayList<String> listOfEventNames = new ArrayList<String>();

		cursor.moveToFirst();
		while(!cursor.isAfterLast()){
			String eventName = cursorToEventName(cursor);
			if(!MyHelper.isRedDay(eventName)){
				listOfEventNames.add(eventName);
			}
			cursor.moveToNext();
		}
		cursor.close();
		return listOfEventNames;
	}


}
